package com.smartlbs.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.smartlbs.baseframe.utils.ConfigFileUtils;
import com.smartlbs.dto.UserOrderDto;
import com.smartlbs.entity.BetInfo;
import com.smartlbs.entity.GameInfo;
import com.smartlbs.entity.PayLog;
import com.smartlbs.entity.UserBasic;
import com.smartlbs.entity.UserOrder;
import com.smartlbs.enums.OrderStatusEnums;
import com.smartlbs.enums.PayTypeEnums;
import com.smartlbs.mapper.BetInfoMapper;
import com.smartlbs.mapper.GameIfonMapper;
import com.smartlbs.mapper.PayLogMapper;
import com.smartlbs.mapper.UserBasicMapper;
import com.smartlbs.mapper.UserOrderMapper;
import com.smartlbs.service.IUserOrderService;
import com.smartlbs.util.StringUtil;
import com.smartlbs.vo.UserOrderVo;

@Service("userOrderService")
public class UserOrderServiceImpl implements IUserOrderService {
	
	@Autowired
	private UserOrderMapper userOrderMapper;
	@Autowired
	private UserBasicMapper userBasicMapper;
	@Autowired
	private PayLogMapper payLogMapper;
	@Autowired
	private BetInfoMapper betInfoMapper;
	@Autowired
	private GameIfonMapper gameInfoMapper;
	
	@Override
	public int addUserOrder(UserOrder userOrder, UserBasic currentUser) {
		int result = 0;
		//
		Integer status = userOrder.getStatus();
		
		if(status == OrderStatusEnums.UN_ACCOUNT.getValue() && StringUtil.getDouble(userOrder.getPoints(), 0) > StringUtil.getDouble(currentUser.getPoints(), 0)){
			return 2;
		}
		
		//是否已结算
		BetInfo betInfo = betInfoMapper.findById(Long.parseLong(userOrder.getBetIds()));
		if(betInfo.getStatus()==2){
			return 3;
		}
		
		//录入订单数据
		userOrder.setUserId(currentUser.getUserId());
		Date date = new Date();
		userOrder.setCreateTime(date);
		userOrder.setUpdateTime(date);
		userOrderMapper.insert(userOrder);
		
		//
		long orderId = userOrder.getOrderId();
		
		if(status == OrderStatusEnums.UN_ACCOUNT.getValue()){//已投注
			//
			Long userId = currentUser.getUserId();
			//
			PayLog payLog = new PayLog();
			
			payLog.setCreateTime(new Date());
			payLog.setUserId(userId);
			payLog.setOutId(orderId+"");
			//待改
			payLog.setPoints("-"+userOrder.getPoints());
			payLog.setType(PayTypeEnums.BET.getValue());
			payLog.setAdminId(0L);
			//
			payLogMapper.insert(payLog);
			
			/*
			 * 
			 */
			UserBasic basic = new UserBasic();
			//
			basic.setUserId(userId);
			
			//
			BigDecimal decimal1 = new BigDecimal(currentUser.getPoints());
			BigDecimal decimal2 = new BigDecimal(userOrder.getPoints());
			BigDecimal decimal = decimal1.subtract(decimal2).setScale(2, RoundingMode.HALF_UP);
			basic.setPoints(decimal.toString());
			
			userBasicMapper.update(basic);
		}
		
		result = 1;
		
		return result;
	}
	
	@Override
	public Integer payOrder(Long orderId, String points) {
		//
		Integer result = 0;
		//
		UserOrder userOrder = userOrderMapper.findById(orderId);
		
		if(userOrder != null){
			/*
			 * 当前版本只有一个押注项
			 */
			BetInfo betInfo = betInfoMapper.findById(Long.parseLong(userOrder.getBetIds()));
			//
			GameInfo gameInfo = gameInfoMapper.findById(userOrder.getGameId());
			
			if(gameInfo.getGameTime().getTime() < new Date().getTime() || betInfo.getStatus()==2){
				result = 2;
			}else{
				//
				UserBasic currentUser = userBasicMapper.findById(userOrder.getUserId());
				if(StringUtil.getDouble(points, 0) > StringUtil.getDouble(currentUser.getPoints(), 0)){
					result = 3;
				}else{
					//
					PayLog payLog = new PayLog();
					
					payLog.setCreateTime(new Date());
					payLog.setUserId(userOrder.getUserId());
					payLog.setOutId(orderId+"");
					//待改
					payLog.setPoints("-"+points);
					payLog.setType(PayTypeEnums.BET.getValue());
					payLog.setAdminId(0L);
					//
					payLogMapper.insert(payLog);
					
					/*
					 * 
					 */
					UserBasic basic = new UserBasic();
					//
					basic.setUserId(userOrder.getUserId());
					
					//
					BigDecimal decimal1 = new BigDecimal(currentUser.getPoints());
					BigDecimal decimal2 = new BigDecimal(points);
					BigDecimal decimal = decimal1.subtract(decimal2).setScale(2, RoundingMode.HALF_UP);
					basic.setPoints(decimal.toString());
					
					userBasicMapper.update(basic);
					
					//
					UserOrder order = new UserOrder();
					order.setOrderId(orderId);
					order.setPoints(points);
					order.setStatus(OrderStatusEnums.UN_ACCOUNT.getValue());
					
					userOrderMapper.update(order);
					
					result = 1;
				}
			}
		}
		
		return result;
	}
	
	/*
	@Override
	public boolean account(Long orderId) {
		//
		UserOrder userOrder = userOrderMapper.findById(orderId);
		//
		BigDecimal decimalByOrder = new BigDecimal(userOrder.getPoints()).multiply(new BigDecimal(userOrder.getRatio()));
		//
		UserBasic basic = userBasicMapper.findById(userOrder.getUserId());
		//
		//
		BigDecimal decimal1 = new BigDecimal(basic.getPoints());
		BigDecimal decimal = decimal1.add(decimalByOrder).setScale(2, RoundingMode.HALF_UP);
		//
		basic = new UserBasic();
		basic.setUserId(userOrder.getUserId());
		basic.setPayPwd(decimal.toString());
		
		userBasicMapper.update(basic);
		
		UserOrder order = new UserOrder();
		order.setOrderId(orderId);
		order.setStatus(OrderStatusEnums.ACCOUNT.getValue());
		order.setUpdateTime(new Date());
		//
		userOrderMapper.update(order);
		return false;
	}
	 */
	
	@Override
	public void delete(Long orderId) {
		UserOrder deleteOrder = new UserOrder();
		deleteOrder.setOrderId(orderId);
		
		userOrderMapper.deleteByOrder(deleteOrder);
	}
	
	@Override
	public void accountByBet(Long betId) {
		/*
		 * 查询已支付的订单
		 */
		UserOrderDto userOrderDto = new UserOrderDto();
		userOrderDto.setStatus(OrderStatusEnums.UN_ACCOUNT.getValue());
		userOrderDto.setBetIds(String.valueOf(betId));
		
		List<UserOrder> userOrderList = userOrderMapper.find(userOrderDto);
		//
		BetInfo betInfo = betInfoMapper.findById(betId);
		if(userOrderList != null && userOrderList.size() > 0){
			
			
			//
			String lIds = betInfo.getlIds();
			String[] split = lIds.split(",");
			Set<String> lIdSet = new HashSet<>(Arrays.asList(split));
			//
			//Set<Integer> lIdSet = StringUtil.transferStr2Set(lIds, ",");
			
			for(UserOrder userOrder:userOrderList){
				UserOrder order = new UserOrder();
				order.setOrderId(userOrder.getOrderId());
				order.setUpdateTime(new Date());
				
				if(lIdSet.contains(userOrder.getlIds())){//赢
					//
					BigDecimal decimalByOrder = new BigDecimal(userOrder.getPoints()).multiply(new BigDecimal(userOrder.getRatio()));
					//
					UserBasic basic = userBasicMapper.findById(userOrder.getUserId());
					//
					//
					BigDecimal decimal1 = new BigDecimal(basic.getPoints());
					BigDecimal decimal = decimal1.add(decimalByOrder).setScale(2, RoundingMode.HALF_UP);
				
					//
					basic = new UserBasic();
					basic.setUserId(userOrder.getUserId());
					basic.setPoints(decimal.toString());
					
					userBasicMapper.update(basic);
					//消费记录
					BigDecimal subtract = decimal.subtract(decimal1);
					PayLog payLog = new PayLog();
					payLog.setAdminId(0L);
					payLog.setOutId(userOrder.getOrderId()+"");
					payLog.setCreateTime(new Date());
					payLog.setPoints(subtract.toString());
					payLog.setType(2);
					payLog.setUserId(userOrder.getUserId());
					
					payLogMapper.insert(payLog);
					order.setStatus(OrderStatusEnums.SUCCESS.getValue());
					userOrderMapper.update(order);
				}else{
					order.setStatus(OrderStatusEnums.FAIL.getValue());
					userOrderMapper.update(order);
				}
			}
		
		}
		//更改为结算状态
		betInfo.setStatus(2);
		betInfoMapper.update(betInfo);
	}
	
	@Override
	public PageInfo<UserOrder> find(Integer pageNum, Integer pageSize, UserOrderDto userOrderDto){
		//删除已过期的 未投注的订单
		UserOrder deleteOrder = new UserOrder();
		deleteOrder.setStatus(OrderStatusEnums.UN_BET.getValue());
		deleteOrder.setGameTime(new Date());
		userOrderMapper.deleteByOrder(deleteOrder);
		
		
		Page<UserOrder> page =PageHelper.startPage(pageNum, pageSize);
		
		if(!StringUtil.containEmpty(userOrderDto.getStatusStr())){
			userOrderDto.setStatusSet(StringUtil.transferStr2Set(userOrderDto.getStatusStr(), ","));
		}
		//
		List<UserOrder> userOrderList = userOrderMapper.find(userOrderDto);
		
		PageInfo<UserOrder> pageInfo = page.toPageInfo();
		//
		List<UserOrderVo> userOrderVoList = new ArrayList<>();
		//
		if(userOrderList != null && userOrderList.size() > 0){
			Map<String, Object> valueMap=ConfigFileUtils.getBetJson();
			
			for(UserOrder userOrder:userOrderList){
				//
				UserOrderVo userOrderVo = new UserOrderVo();
				
				try {
					BeanUtils.copyProperties(userOrderVo, userOrder);
				} catch (Exception e) {
					e.printStackTrace();
				}
				
				//
				GameInfo gameInfo = gameInfoMapper.findById(userOrder.getGameId());
				
				userOrderVo.setBetName(gameInfo.getBetName());
				
				if(userOrderVo.getStatus() == OrderStatusEnums.SUCCESS.getValue()){
					//
					BigDecimal decimal = new BigDecimal(userOrder.getPoints()).multiply(new BigDecimal(userOrder.getRatio()));
					String winPoints = decimal.setScale(2, RoundingMode.HALF_UP).toString();
					userOrderVo.setWinPoints(winPoints);
				}
				
				userOrderVo.setG(valueMap.get(String.valueOf(userOrderVo.getlIds().split("-")[0])));
				
				userOrderVoList.add(userOrderVo);
			}
		}
		
		pageInfo.getList().removeAll(pageInfo.getList());
		pageInfo.getList().addAll(userOrderVoList);
		
		return pageInfo;
	}
	
	@Override
	public List<Map> queryTitle(UserOrderDto userOrderDto) {
		return userOrderMapper.queryTitle(userOrderDto);
	}
}